<template>
  <div>
    <el-card shadow="always" :body-style="{ padding: '20px' }">
      <template #header>
        <el-button icon="ele-Plus" type="primary" @click="addDialog"
          >添加</el-button
        >
      </template>
      <!-- 
      tabel属性:
        data:当前表格对应的数组

      el-table-column属性
        type:index:代表当前列是序号
        label:代表当前列的表头
        prop:值是一个标识而已,让当前组件去数组数据中每一条找到对应的值组成一列

     -->
      <el-table :data="trademarkList" border stripe v-loading="tableLoading">
        <el-table-column type="index" width="80" label="序号"></el-table-column>
        <el-table-column label="品牌名称" prop="tmName"></el-table-column>
        <el-table-column label="品牌logo">
          <!-- table-column 作用域插槽提供 row是当前列所在行的整个数据,$index是当前列所在行的下标-->
          <template v-slot="{ row }">
            <img width="100" :src="row.logoUrl" alt="" />
          </template>
        </el-table-column>
        <el-table-column label="操作">
          <template v-slot="{ row }">
            <el-button
              type="warning"
              size="small"
              icon="ele-Edit"
              @click="updateTm(row)"
              >修改</el-button
            >
            <!-- 
            el-popconfirm组件:气泡确认框
              - title:确认框的内容
              - confirmButtonText:确认按钮的文字
              - cancelButtonText:取消按钮的文字
              - confirmButtonType:确认按钮的按钮类型
              - cancelButtonType:取消按钮的按钮类型
              - icon:图标
              - iconColor:图标颜色
              - @confirm:确认的事件
           -->
            <el-popconfirm
              title="是否确认删除该品牌"
              confirmButtonText="确认"
              cancelButtonText="取消"
              confirmButtonType="primary"
              cancelButtonType="text"
              icon="ele-Delete"
              iconColor="#f90"
              @confirm="deleteTrademark(row.id)"
            >
              <template #reference
                ><el-button type="danger" size="small" icon="ele-Delete"
                  >删除</el-button
                ></template
              >
            </el-popconfirm>
          </template>
        </el-table-column>
      </el-table>

      <!-- 
      current-page:当前页
      page-size:每页数量
      page-sizes:可以选择每页条数的选项
      total:数据总数量
      layout:布局排序
     -->
      <el-pagination
        v-model:current-page="currentPage"
        v-model:page-size="pageSize"
        :page-sizes="[3, 5, 7, 9]"
        layout="  prev, pager, next,sizes,total"
        :total="totle"
        :style="{ marginTop: '20px' }"
      />
    </el-card>

    <!-- 
    dialog组件属性:
      v-model:是否显示 Dialog
      width:Dialog的宽度
      before-close:关闭前的回调函数
    dialog插槽:
      1.具名插槽header:弹窗的标题
      2.具名插槽footer:按钮区内容
      3. 默认插槽:Dialog 的内容

   -->
    <el-dialog v-model="dialogVisible" width="50%">
      <template #header> {{ tmInfo.id ? "修改" : "新增" }}品牌 </template>
      <!-- 
      el-form组件的属性:
        label-width:每一个表单都是label字符和表单元素组成,可以统一控制label的宽度
        :inline:是否是行内表单
        size:表单尺寸

      el-form-item组件:
        每一个表单元素必须配置一个el-form-item组件
        label属性：就是当前表单的label值


     -->
      <el-form
        label-width="100px"
        :inline="false"
        size="default"
        :model="tmInfo"
        :rules="tmRules"
        ref="ruleFormRef"
      >
        <el-form-item label="品牌名称" prop="tmName">
          <el-input v-model="tmInfo.tmName"></el-input>
        </el-form-item>
        <el-form-item label="品牌LOGO" prop="logoUrl">
          <!-- 
          单独文件上传的组件el-upload组件
            - action：图片上传的地址
            - show-file-list：是否展示已经上传的图片列表
            - on-success:文件上传成功钩子函数 (response: any, uploadFile: UploadFile, uploadFiles: UploadFiles) => void
            - before-upload:上传文件之前的钩子 (rawFile: UploadRawFile) => Awaitable<void | undefined | null | boolean | File | Blob>
         -->
          <el-upload
            class="avatar-uploader"
            :action="`${baseUrl}/admin/product/upload`"
            :show-file-list="false"
            :on-success="handleAvatarSuccess"
            :before-upload="beforeAvatarUpload"
          >
            <img v-if="tmInfo.logoUrl" :src="tmInfo.logoUrl" class="avatar" />
            <el-icon v-else class="avatar-uploader-icon"><ele-Plus /></el-icon>
          </el-upload>
        </el-form-item>
      </el-form>

      <template #footer>
        <span>
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button type="primary" @click="addOrUpdateTrademark"
            >确认</el-button
          >
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script lang="ts">
import { defineComponent } from "vue";

export default defineComponent({
  name: "Trademark",
});
</script>

<script setup lang="ts">
import { onMounted, reactive, ref, watch } from "vue";
import {
  reqTrademarkList,
  reqAddTrademark,
  reqUpdateTrademark,
  reqDeleteTrademark,
  type trademarkItemType,
} from "@/api/trademark";
import type { trademarkListType } from "@/api/trademark";
import { ElMessage, type FormRules, type UploadProps } from "element-plus";

//品牌列表数据
const trademarkList = ref<trademarkListType>([]);

//页码逻辑
const currentPage = ref(1); //当前页
const pageSize = ref(3); //每页条数
const totle = ref(0); //总条数

//table的是否loading状态的数据
const tableLoading = ref(false);

//封装一个请求分页列表的方法(方便未来数据改变的时候再次请求)
const getTrademarkList = async () => {
  //开启table的loading状态
  tableLoading.value = true;
  //发送请求
  const re = await reqTrademarkList(currentPage.value, pageSize.value);
  //赋值操作
  trademarkList.value = re.records;
  totle.value = re.total;

  //取消table的loading状态
  tableLoading.value = false;
};

//初始化发送品牌分页列表请求
onMounted(async () => {
  getTrademarkList();
});

//监听页码的改变，从而重新发送请求
watch([currentPage, pageSize], () => {
  getTrademarkList();
});

//弹窗的是否展示的数据
const dialogVisible = ref(false);
//收集公共请求前缀，从环境变量中读取
const baseUrl = import.meta.env.VITE_API_URL;
/* //新建一个上传图片的预览图片url数据
const imageUrl = ref("");
//新建一个收集品牌名称的数据
const tmName = ref(""); */
//我们可以直接定义一个对象 用来收集或者绑定dialog的数据
const tmInfo = ref<trademarkItemType>({
  logoUrl: "",
  tmName: "",
});

//创建一个保存form组件的数据
const ruleFormRef = ref();

//表单校验的自定义校验规则函数
const checkTmName = (rule: any, value: any, callback: any) => {
  /* if (value.length < 5 && value.length > 2) {
    return true;
  }
  return false; */
  //value就是被校验的值
  //自定义校验规则可以通过返回的布尔值来确认是否通过这个规则

  return value.length <= 5 && value.length >= 2;
};

//弹出框的表单校验规则
const tmRules = reactive<FormRules>({
  //在规则中使用validator来使用自定义规则函数
  tmName: [
    { required: true, message: "品牌名称不能为空", trigger: "blur" },
    { validator: checkTmName, message: "长度应该是2-5", trigger: "blur" },
  ],
  logoUrl: [{ required: true, message: "品牌图片不能为空", trigger: "blur" }],
});

//点击新增按钮打开弹窗的事件回调函数
const addDialog = async () => {
  //打开弹窗
  dialogVisible.value = true;

  //清空之前的校验规则（异步）
  try {
    await ruleFormRef.value.clearValidate();

    //重置表单
    tmInfo.value = {
      logoUrl: "",
      tmName: "",
    };
  } catch (e) {
    ElMessage.error("清空上一次的校验规则失败");
  }
};

//上传图片的事件回调函数--文件上传成功的钩子函数
const handleAvatarSuccess: UploadProps["onSuccess"] = (response) => {
  // console.log(response, uploadFile);
  //上传成功以后，会响应数据response response中有一个data就是上传后的图片地址
  tmInfo.value.logoUrl = response.data;
};

//上传图片的事件回调函数-文件上传之前的钩子函数
const beforeAvatarUpload: UploadProps["beforeUpload"] = (rawFile) => {
  //判断文件的类型
  if (rawFile.type !== "image/jpeg") {
    ElMessage.error("我们这里只能上传jpg图片");
    return false;
  } else if (rawFile.size / 1024 / 1024 > 2) {
    ElMessage.error("品牌图片的大小超过2M");
    return false;
  }
  return true;
};

//弹窗内新增品牌的请求事件回调函数
const addOrUpdateTrademark = async () => {
  /* //收集请求需要的参数
  const tmInfo: trademarkItemType = {
    logoUrl: imageUrl.value,
    tmName: tmName.value,
  }; */

  //表单整体校验
  try {
    await ruleFormRef.value.validate();

    //当前的事件可能发送的新增,也可能发送的修改,需要通过tmInfo的id来确认
    if (tmInfo.value.id) {
      //发送请求
      await reqUpdateTrademark(tmInfo.value);
      //弹窗提醒
      ElMessage.success("修改品牌成功");
    } else {
      //发送新增请求
      await reqAddTrademark(tmInfo.value);
      //弹窗提醒
      ElMessage.success("新增品牌成功");
    }

    //关闭弹窗
    dialogVisible.value = false;

    //重新发送品牌列表的请求
    getTrademarkList();
  } catch (e) {
    ElMessage.error("整体校验失败");
  }
};

//修改品牌的按钮事件回调函数
const updateTm = (row: trademarkItemType) => {
  //获取当前修改按钮所在的这条数据 赋值给弹窗内控制数据的对象 tmInfo
  //因为tmInfo绑定的是弹窗内的数据，所以一旦赋值并打开弹窗，就会回填数据

  //如果把row直接赋值给tmInfo,tmInfo是双向绑定输入框的,只要输入框内容改变,则row的数据也会改变,品牌列表的内容也会改变
  //所以我们要经过拷贝把row的值赋值给tmInfo(当前数据结构简单,只需要浅拷贝即可)
  tmInfo.value = { ...row };

  //打开dialog弹窗
  dialogVisible.value = true;

  //清空之前的校验规则
  ruleFormRef.value.clearValidate();
};

//删除品牌的事件回调函数
const deleteTrademark = async (id: number) => {
  //发送删除请求
  await reqDeleteTrademark(id);

  //弹窗提示
  ElMessage.success("删除数据成功");

  //重新发送分页列表请求
  getTrademarkList();
};
</script>

<style scoped lang="scss">
.avatar-uploader .avatar {
  width: 178px;
  height: 178px;
  display: block;
}
</style>

<style lang="scss">
.avatar-uploader .el-upload {
  border: 1px dashed var(--el-border-color);
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  transition: var(--el-transition-duration-fast);
}

.avatar-uploader .el-upload:hover {
  border-color: var(--el-color-primary);
}

.el-icon.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 178px;
  height: 178px;
  text-align: center;
}
</style>
